
// <copyright file="ExcelSheetDataReaderStrategy.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The excel sheet data reader strategy.
// </summary>

namespace SubhadraSolutions.Sharp.Utils.Data.Helpers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.RegularExpressions;

    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Spreadsheet;

    /// <summary>
    /// The excel sheet data reader strategy.
    /// </summary>
    public sealed class ExcelSheetDataReaderStrategy : AbstractDataReaderStrategy<Row>
    {
        #region Fields

        /// <summary>
        /// The shared string table part.
        /// </summary>
        private readonly SharedStringTablePart _sharedStringTablePart;

        /// <summary>
        /// The worksheet.
        /// </summary>
        private readonly Worksheet _worksheet;

        /// <summary>
        /// The columns.
        /// </summary>
        private IList<KeyValuePair<string, Type>> _columns;

        /// <summary>
        /// The enumerator.
        /// </summary>
        private IEnumerator<Row> _enumerator;

        #endregion Fields

        #region Constructors and Finalizers

        /// <summary>
        /// Initializes a new instance of the <see cref="ExcelSheetDataReaderStrategy"/> class.
        /// </summary>
        /// <param name="worksheet">
        /// The worksheet.
        /// </param>
        /// <param name="sharedStringTablePart">
        /// The shared string table part.
        /// </param>
        public ExcelSheetDataReaderStrategy(Worksheet worksheet, SharedStringTablePart sharedStringTablePart)
        {
            this._worksheet = worksheet;
            this._sharedStringTablePart = sharedStringTablePart;
        }

        #endregion Constructors and Finalizers

        #region Delegates

        /// <summary>
        /// The populate item array callback.
        /// </summary>
        /// <param name="items">
        /// The items.
        /// </param>
        /// <param name="objectArray">
        /// The object array.
        /// </param>
        private delegate void PopulateItemArrayCallback(string[] items, object[] objectArray);

        #endregion Delegates

        #region Methods

        /// <summary>
        /// The dispose.
        /// </summary>
        /// <param name="disposing">
        /// The disposing.
        /// </param>
        protected override void Dispose(bool disposing)
        {
        }

        /// <summary>
        /// The get columns.
        /// </summary>
        /// <returns>
        /// The <see cref="IList"/>.
        /// </returns>
        protected override IList<KeyValuePair<string, Type>> getColumns()
        {
            return this._columns;
        }

        /// <summary>
        /// The initialize protected.
        /// </summary>
        protected override void InitializeProtected()
        {
            this._columns = ExcelHelper.GetColumnNames(this._worksheet, this._sharedStringTablePart);
            IEnumerable<Row> dataRows = from row in this._worksheet.Descendants<Row>() where row.RowIndex > 1 select row;
            this._enumerator = dataRows.GetEnumerator();
            base.InitializeProtected();
        }

        /// <summary>
        /// The populate item array.
        /// </summary>
        /// <param name="obj">
        /// The obj.
        /// </param>
        /// <param name="itemArray">
        /// The item array.
        /// </param>
        protected override void populateItemArray(Row obj, object[] itemArray)
        {
            // for (int i = 0; i < itemArray.Length; i++)
            // {
            // Cell cell = GetCellFromRow(row,i) ;
            // itemArray[i] = cell.CellValue == null ? null : cell.CellValue.InnerText;
            // }
            int j = 0;
            int n;
            var catalogueValues = from cell in obj.Descendants<Cell>() select new { CellVal = cell.CellValue != null ? (int.TryParse(cell.CellValue.InnerText, out n) ? (cell.DataType != null && cell.DataType == CellValues.SharedString ? this._sharedStringTablePart.SharedStringTable.ChildElements[int.Parse(cell.CellValue.InnerText)].InnerText : cell.CellValue.InnerText) : cell.CellValue.Text) : string.Empty, CelRef = ExcelHelper.GetColumnNumber(Regex.Replace(cell.CellReference.Value, @"\d", string.Empty)) };

            for (int i = 0; i < itemArray.Length; i++)
            {
                itemArray[i] = null;
            }

            foreach (var item in catalogueValues)
            {
                int index = item.CelRef - 1;
                if (index < itemArray.Length)
                {
                    string s = StringHelper.Trim(item.CellVal);
                    if (s == "#N/A")
                    {
                        s = null;
                    }

                    itemArray[index] = s;
                    j++;
                }

                if (j == itemArray.Length)
                {
                    break;
                }
            }
        }

        /// <summary>
        /// The read next object.
        /// </summary>
        /// <returns>
        /// The <see cref="Row"/>.
        /// </returns>
        protected override Row readNextObject()
        {
            if (this._enumerator.MoveNext())
            {
                return this._enumerator.Current;
            }

            return null;
        }

        #endregion Methods
    }
}